use idgen::IDGen;
use serde_json::Value;
use tokio::fs;

use crate::{
    APP_DIR, dao::{
        self, config, momento::{Momento, PREVIEW_NUM}
    }, utils::{
        date_util::{self},
        file_util,
        response::R,
    }
};

#[tauri::command]
pub async fn get_momento_list(book_id: String, pid: String, is_folder: Option<i16>) -> R<Vec<Momento>> {
    R::data(dao::momento::get_list_by_book_id(book_id, pid, "".to_string(), is_folder).await)
}


#[tauri::command]
pub async fn get_momento_tree(book_id: String, pid: String, is_folder: Option<i16>) -> R<Value> {
    println!("is_folder  {:?}", is_folder);
    R::data(dao::momento::get_tree(book_id, pid, is_folder).await)
}

#[tauri::command]
pub fn add_momento(
    pid: String, 
    book_id: String,
    note_content: String,
    title: String,
    heading: String,
    is_folder: i16
) -> R<String> {
    let idgen = IDGen::new(1);
    let id = idgen.new_id();
    let mut momento = Momento::default();
    momento.id = id.to_string();
    momento.pid = Some(pid);
    momento.book_id = book_id;
    momento.note_content = note_content.clone();
    momento.title = title;
    momento.heading = heading;
    momento.is_folder = is_folder;
    if note_content.len() > PREVIEW_NUM {
        momento.file_path = dao::momento::set_file_path(momento.id.clone(), momento.file_path);
    }
    println!("isFolder {}", is_folder);
    if dao::momento::save(momento) {
        println!("id {}", id);
        return R::data(Some(id.to_string()));
    }
    R::fail("更新失败")
}

#[tauri::command]
pub fn save_momento(pid: String, book_id: String, note_content: String) -> R<bool> {
    let data = dao::momento::str_to_momento(note_content.clone());
    if data.is_none() {
        let mut momento: Momento = Momento::default();
        let idgen = IDGen::new(1);
        let id = idgen.new_id();
        momento.id = id.to_string();
        momento.book_id = book_id;
        if !pid.is_empty() {
            momento.pid = Some(pid);
        }
        momento.note_content = note_content.clone();
        momento.title = note_content.clone();
        momento.heading = note_content.clone();
        if note_content.len() > PREVIEW_NUM {
            momento.file_path = dao::momento::set_file_path(momento.id.clone(), momento.file_path);
        }

        if dao::momento::save(momento) {
            return R::success();
        }
    } else {
        let mut momento: Momento = data.unwrap();
        let idgen = IDGen::new(1);
        let id = idgen.new_id();
        momento.id = id.to_string();
        momento.book_id = book_id;
        if !pid.is_empty() {
            momento.pid = Some(pid);
        }
        momento.note_content = note_content.clone();
        momento.heading = momento.title.clone();
        if note_content.len() > PREVIEW_NUM {
            momento.file_path = dao::momento::set_file_path(momento.id.clone(), momento.file_path);
        }
        let path = momento.file_path.clone();
        if dao::momento::save(momento) {
            if !path.is_empty() {
                file_util::write_file(path, note_content);
            }
            return R::success();
        }
    }
    R::fail("更新失败")
}


#[tauri::command]
pub async fn update_momento_title_heading(id: String, title: String, heading: String) -> R<bool> {
    let mut momento = Momento::default();
    momento.id = id;
    momento.title = title;
    momento.heading = heading;
    let result = dao::momento::update_momento_title_heading(momento).await;
    match result {
        Some(result) => {
            return R::data(Some(result));
        }
        None => {
            return R::success();
        }
    }
}


#[tauri::command]
pub async fn update_momento(
    id: String,
    pid: String,
    book_id: String,
    note_content: String,
    title: String,
    heading: String,
    date: i64,
) -> R<String> {
    let mut momento = Momento::default();
    momento.id = id.clone();
    momento.book_id = book_id.clone();
    if !pid.is_empty() {
        momento.pid = Some(pid.clone());
    }
    momento.note_content = note_content.clone();
    momento.title = title;
    momento.date = date;
    momento.heading = heading;
    let db_momento = dao::momento::get_info_by_id(id.clone()).await;
    if let Some(db) = db_momento {
        if !db.file_path.is_empty() {
            momento.file_path = db.file_path;
        }
        if db.add_date.is_empty() {
            momento.add_date = date_util::get_ymd_str_by_m(db.create_time);
        } else {
            momento.add_date = db.add_date;
        }
    }
    if !note_content.is_empty() {
        //file
        if note_content.len() > PREVIEW_NUM {
            momento.file_path = dao::momento::set_file_path(momento.id.clone(), momento.file_path);
        }
    }

    let result = dao::momento::update_tokio(momento).await;
    match result {
        Some(result) => {
            return R::success();
        }
        None => {
            return R::success();
        }
    }
}



#[tauri::command]
pub async fn update_momento_sort(
    id: String,
    sort: i16,
    parent_key: String,
    book_id: String
) -> R<String> {
    let mut momento = Momento::default();
    momento.id = id.clone();
    momento.sort = sort;
    if !book_id.is_empty() {
        momento.book_id = book_id;
    }
    momento.pid = Some(parent_key.clone());
    if !parent_key.is_empty() {
        if let Some(info) = dao::momento::get_info_by_id(id).await {
            if info.pid.is_none() || info.pid.unwrap() != parent_key {
                momento.pid = Some(parent_key.clone());
                let result = dao::momento::update_sort_tokio(momento).await;
                match result {
                    Some(_) => {
                        if let Some(list) = dao::momento::get_list_by_book_id("".to_string(), parent_key, "".to_string(), None).await {
                            for mut ele in list {
                                ele.note_content = "".to_string();
                                dao::momento::update_sort_tokio(ele).await;
                            }
                        }
                        return R::success();
                    }
                    None => {
                        return R::success();
                    }
                }
            }
        } else {
            return R::success();
        }
    }
    log::info!("-----{:?}", momento);
    let result = dao::momento::update_sort_tokio(momento).await;
    match result {
        Some(_) => {
            return R::success();
        }
        None => {
            return R::success();
        }
    }
}


#[tauri::command]
pub async fn update_momento_content(
    id: String,
    title: String,
    note_content: String,
    open_type: String,
) -> R<String> {
    let mut momento = Momento::default();
    momento.id = id.clone();
    momento.title = title;
    momento.note_content = note_content.clone();
    momento.open_type = open_type;
    let db_momento = dao::momento::get_info_by_id(id.clone()).await;
    if let Some(db) = db_momento {
        if !db.file_path.is_empty() {
            if db.file_path.starts_with("doc") {
                momento.file_path = db.file_path;
            } else {
                momento.file_path = dao::momento::set_file_path(momento.id.clone(), "".to_string());
            }
            
        }
        if db.add_date.is_empty() {
            momento.add_date = date_util::get_ymd_str_by_m(db.create_time);
        } else {
            momento.add_date = db.add_date;
        }
    }

    if dao::momento::update_content_tokio(momento).await {
        return R::success();
    } else {
        return R::fail("更新失败！");
    }
}




#[tauri::command]
pub async fn delete_momento(id: String) -> R<bool> {
    if let Some(num) = dao::momento::get_count_by_pid(id.clone()).await {
        if num {
            return R::fail("目录有子集，不能删除！");
        } else {
            if let Some(momento) = dao::momento::get_info_by_id(id.clone()).await {
                if !momento.file_path.is_empty() {
                    let _ = fs::remove_file(momento.file_path).await;
                }
            }
            if dao::momento::delete_by_id(id).await {
                return R::success();
            }
        }
    }
    R::fail("删除失败")
}

#[tauri::command]
pub async fn get_info_by_id(id: String) -> R<Momento> {
    if let Some(mut momento) = dao::momento::get_info_by_id(id.clone()).await {
        if !momento.file_path.is_empty() {
            let dic_path;
            match config::get_dic_path().await {
                Some(path) => {
                    dic_path = path;
                },
                None => {
                    dic_path = APP_DIR.get().unwrap().to_string();
                    config::up_dir_config(dic_path.clone()).await;
                },
            }
            match file_util::read_to_string(&(dic_path + &momento.file_path)).await {
                Some(text) => {
                    log::info!("读取文件成功");
                    let (content, list, _is_up) = dao::momento::set_files(text);
                    momento.note_content = content.clone();
                    momento.files = list;
                    if _is_up {
                        dao::momento::update_content_tokio(momento.clone()).await;
                    }
                },
                None => {
                    log::info!("读取文件失败！{}", momento.file_path);
                },
            }
        }
        return R::data(Some(momento));
    }
    R::data(None)
}
